package org.goldenport.g3

import java.util.UUID

/**
 * @since   Apr. 24, 2010
 * @version Oct.  4, 2010
 * @author  ASAMI, Tomoharu
 */
abstract class G3Id(
  val uuid: String,

  /**
   * Host real nano time on which the agent is running.
   * System.nanoTime
   */
  val time: Long
) {
  var number: Int = G3Id.getHintCount()
  var nickname: String = "anonymous"

  def toText = uuid + ":" + time

  // Object
  override def equals(o: Any): Boolean = {
    o match {
      case id: G3Id => {
        id.uuid == uuid && id.time == time
      }
      case _ => false
    }
  }

  override def hashCode(): Int = {
    uuid.hashCode + time.toInt
  }

  // for debug use
  override def toString() = {
    "#%s(%s)".format(number, nickname)
  }
}

object G3Id {
  private var hint_count = 0

  def getHintCount() = {
    hint_count += 1
    hint_count
  }

  def createParcelId(): G3ParcelId = {
    val (uuid, time) = generate_id_parts
    new G3ParcelId(uuid, time)
  }

  def createTicketId(): G3TicketId = {
    val (uuid, time) = generate_id_parts
    new G3TicketId(uuid, time)
  }

  def createChannelId(): G3ChannelId = {
    val (uuid, time) = generate_id_parts
    new G3ChannelId(uuid, time)
  }

  def createSessionId(): G3SessionId = {
    val (uuid, time) = generate_id_parts
    new G3SessionId(uuid, time)
  }

  def createJobId(): G3JobId = {
    val (uuid, time) = generate_id_parts
    new G3JobId(uuid, time)
  }

  def createUnitofworkId(): G3UnitofworkId = {
    val (uuid, time) = generate_id_parts
    new G3UnitofworkId(uuid, time)
  }

  def createEventId(): G3EventId = {
    val (uuid, time) = generate_id_parts
    new G3EventId(uuid, time)
  }

  private def generate_id_parts = {
    val uuid = UUID.randomUUID.toString
    val time = System.nanoTime
    (uuid, time)
  }
}

class G3ParcelId(uuid: String, time: Long) extends G3Id(uuid, time)

class G3TicketId(uuid: String, time: Long) extends G3Id(uuid, time)

class G3ChannelId(uuid: String, time: Long) extends G3Id(uuid, time)

class G3SessionId(uuid: String, time: Long) extends G3Id(uuid, time)

class G3JobId(uuid: String, time: Long) extends G3Id(uuid, time)

class G3TransactionId(uuid: String, time: Long) extends G3Id(uuid, time)

class G3UnitofworkId(uuid: String, time: Long) extends G3Id(uuid, time)

class G3EventId(uuid: String, time: Long) extends G3Id(uuid, time)
